/////////////////////////////////////////////////////////////////////////////////////////////
//
//      COPYRIGHT 2010 MYLES HATHCOCK
//
//      This source code is provided for all, Open-Source, under this OpenBSD License.
//      It follows all terms and agreements listed there.
//
//      All structure code comments should be in doxygen format.
//
/////////////////////////////////////////////////////////////////////////////////////////////

#include "HE_TimingManager.hpp"

/// Definitions for cTimingManager methods

/////////////////////////////
//
//  Construction
//
/////////////////////////////

cTimingManager::cTimingManager()
{
    //  Any initialization should take place here. For now, all methods are bogus, just test to compile
    /// TODO.
    mDebuggingOutput = false;

}

///////////////////////////////////////////////////////////////

/////////////////////////////////
//
//  Destruction
//
/////////////////////////////////

cTimingManager::~cTimingManager()
{
    //  Delete any memory that has been grabbed while here, and delete pointers and containers
    /// TODO.

}

/////////////////////////////////////////////////////////////////

////////////////////////////
//
//  SetFrequency
//
////////////////////////////

void cTimingManager::SetFrequency( int Frequency )
{
    //  All we need to do here is set our member to the arg of the function.
    mCurrentFrequency = Frequency;

    //  Limit our frequency
    if ( mCurrentFrequency < 10 )   mCurrentFrequency = 10;
    if ( mCurrentFrequency > 50 )   mCurrentFrequency = 50;

    //  And calculate our sec per rti
    mSecPerRTI = (double)( 1.0 / mCurrentFrequency );

}

///////////////////////////////////////////////////////////////

///////////////////////////
//
//  StartTimer
//
///////////////////////////

void cTimingManager::StartTimer()
{
    //  To start our timer, we're simply going to call GetTimeOfDay and save into our starting time member var
    gettimeofday( &sStartingTime, NULL );
}

////////////////////////////////////////////////////////////////

////////////////////////////////
//
//  FinishRTI
//
////////////////////////////////

void cTimingManager::FinishRTI()
{
    //  To finish an RTI, we call GetTimeOfDay again and set it as the ending time
    gettimeofday( &sFinishingTime, NULL );

    //  Lets extract meaningful information from our times
    mStartingTime       = sStartingTime.tv_sec * 1000000 + sStartingTime.tv_usec;
    mFinishingTime      = sFinishingTime.tv_sec * 1000000 + sFinishingTime.tv_usec;

    //  And now set our waiting time.
    mWaitingTime  = - ( mFinishingTime - mStartingTime );

    if ( mDebuggingOutput ) printf( "Time Difference between calls is: %lf microseconds\n", mWaitingTime );

    mWaitingTime += ( mSecPerRTI * 1000000 );

    //  Handle overframing
    if ( mWaitingTime > 0 )
    {
        //  If this is NOT true, we've overframed, and should resume instructions ASAP. Dont wait.
        mWait_USec = mWaitingTime;
        usleep ( mWait_USec );
    }

    /// DEBUGGING
    if ( mDebuggingOutput ) printf( "Wait Time this RTI = %lf microseconds\n", mWaitingTime );

    if ( mDebuggingOutput ) printf( "Current update inverval = %lf seconds. This updates at %i Hertz.\n", mSecPerRTI, mCurrentFrequency );

}


